﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WebeTerm.PlugIns;
using System.Text.RegularExpressions;

namespace WebeTerm.ClearQ
{
    /// <summary>
    /// 自动清Q插件
    /// </summary>
    public sealed class ClearQPlugIn : BaseTermSequencePlugIn<QResult,QConfig>
    {
        #region 私有变量定义
        private string __QMessageTmp = @"TC,GQ,RP,KK,RE,SR,TL,SC";
        private string __QChangedTmp = @"HX|UN|NO|UC";
        private string m_TopMessageType = string.Empty;
        #endregion

        #region 插件构造函数
        /// <summary>
        /// Initializes a new instance of the <see cref="ClearQPlugIn"/> class.
        /// </summary>
        public ClearQPlugIn() : base() {
            Works.Add(this.SI);
            Works.Add(this.QT);
            Works.Add(this.QS);
            Works.Add(this.QN);
            Works.Add(this.PN);
            Works.Add(this.NONEQ);
            Works.Add(this.QNE);
        }
        #endregion

        #region 基类重写
        /*
        /// <summary>
        /// 经过指令结果字符串分析插件数据结果.
        /// </summary>
        /// <param name="Cmd">发送的指令.</param>
        /// <param name="Result">指令结果.</param>
        /// <returns>List{QResult}.</returns>
        protected override List<QResult> GetStreamResult(string Cmd, string Result)
        {
            __QMessageTmp = (PlugInConfig.QMessageTmp ?? new List<string>()).Count == 0 ? __QMessageTmp : string.Join(",", PlugInConfig.QMessageTmp);
            List<QResult> result = new List<QResult>();
            List<string> messageTypes = __QMessageTmp.Split(new char[] { ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            if (Regex.IsMatch(Cmd, @"^QT", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                foreach (Match m in Regex.Matches(Result, @"([A-Z]{2})\s+(\d{4})\s+(\d{4})", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                {
                    if (Regex.IsMatch(m.Groups[2].Value, @"[1-9]", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                        if (messageTypes.Count(l => l.ToLower().Trim() == m.Groups[1].Value.ToLower().Trim()) > 0)
                        {
                            result.Add(new QResult()
                            {
                                QMessageType = m.Groups[1].Value,
                                QMessageCount = m.Groups[2].Value,
                                QMessage = Result
                            });
                            __QMessageType.Enqueue(m.Groups[1].Value);
                        }
                }
            }
            else if (Regex.IsMatch(Cmd, @"^QN([E]{0})|^QS|^PN", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                var m = Regex.Match(Result, @"(\s+(\([\s0-9]+\)))+", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (m.Success)
                {
                    result.Add(new QResult()
                    {
                        QMessageNo = m.Groups[1].Captures[1].Value,
                        QMessageCount = m.Groups[1].Captures[0].Value,
                        QMessage = Result,
                        PNRNo = GetPNRCode(Result),
                        HasChanged = HasQMessageChange(Result),
                        EmployeeNo = GetEmployeeNo(Result),
                        QMessageType = m_TopMessageType
                    });
                }
            }
            __QMessage = new StringBuilder();
            return result.Distinct().ToList();
        }
        */


        /// <summary>
        /// 变更判断
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        private bool HasQMessageChange(string packet)
        {
            bool flag = false;
            string Rule = (PlugInConfig.QChangedTmp ?? new List<string>()).Count == 0 ? __QChangedTmp : string.Join(",", PlugInConfig.QChangedTmp);

            MatchCollection ms = Regex.Matches(packet, @"\s{0,}(\d+)\.\s{0,}(([A-Z0-9]{2})(\d{1,}))\s+[A-Z]{1}\s{0,}([A-Z]{2}[0-9]{2}[A-Z]{3})\s+([A-Z]{6})\s+(([A-Z]{2})\d+)\s+(\d{4})[\+]?\s+(\d{4})[\+]?", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            List<Match> UnMs = (from Match m in ms
                                where Regex.IsMatch(m.Groups[8].Value, Rule, RegexOptions.Multiline | RegexOptions.IgnoreCase) //m.Groups[8].Value.ToUpper() == @"UN" || m.Groups[8].Value.ToUpper() == @"HX"
                                select m).ToList();
            flag = UnMs.Count > 0;

            if (Regex.IsMatch(packet, @"THIS\s+PNR\s+WAS\s+ENTIRELY\s+CANCELLED", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                flag = false;

            return flag;
        }

        /// <summary>
        /// 获取PNR编码
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        private string GetPNRCode(string packet)
        {
            string pnrCode = string.Empty;
            packet.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Select(l => l.Trim()).ToList().ForEach(l =>
            {
                Match m = Regex.Match(l, @"\s+([A-Z0-9]{6})$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (m.Success)
                {
                    pnrCode = m.Groups[1].Value;
                    return;
                }
            });

            return pnrCode;
        }

        /// <summary>
        /// 获取订票员用户标识
        /// </summary>
        /// <param name="packet"></param>
        /// <returns></returns>
        private string GetEmployeeNo(string packet)
        {
            string employeeNo = string.Empty;
            (PlugInConfig.QRule ?? new List<string>() { @"(\s{0,}\d+\.)REM\s+\d{4}\s+\d{4}\s+([A-Z0-9\-]+)" }).ForEach(l =>
            {
                Regex.Matches(packet, l, RegexOptions.IgnoreCase | RegexOptions.Multiline).Cast<Match>().ToList().ForEach(r =>
                {
                    employeeNo = r.Groups[2].Value;
                });
            });
            return employeeNo;
        }
        #endregion

        #region 结果集合处理方法
        /// <summary>
        /// 本轮清Q已完成
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        private List<QResult> NONEQ(string Cmd, string Result)
        {
            if (Regex.IsMatch(Result, @"Q\s+EMPTY", RegexOptions.Multiline | RegexOptions.IgnoreCase)
            ||
            Regex.IsMatch(Result, @"WORKING\s+Q", RegexOptions.Multiline | RegexOptions.IgnoreCase)
            )
            {
                SendStream(@"QNE");
            }
            return null ;
        }

        /// <summary>
        /// 起始指令
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        private List<QResult> SI(string Cmd, string Result)
        {
            if (Regex.IsMatch(Cmd, @"^SI", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                SendStream(@"QT");
            }
            return null;
        }

        /// <summary>
        /// IG指令处理
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        private List<QResult> QNE(string Cmd, string Result)
        {
            if (Regex.IsMatch(Cmd, @"^QNE", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                //if (__QMessageType.Count == 0)
                //{
                //    Disconnect();
                //}
                //else {
                //    m_TopMessageType = __QMessageType.Dequeue();
                SendStream(@"QT");
                //}
            }
            return null;
        }

        /// <summary>
        /// 收取QS SR
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        private List<QResult> QT(string Cmd, string Result)
        {
            List<QResult> results = new List<QResult>();
            if (
                Regex.IsMatch(Cmd, @"^QT", RegexOptions.IgnoreCase | RegexOptions.Multiline)
                )
            {
                #region 分析信箱类型
                __QMessageTmp = (PlugInConfig.QMessageTmp ?? new List<string>()).Count == 0 ? __QMessageTmp : string.Join(",", PlugInConfig.QMessageTmp);
                List<QResult> result = new List<QResult>();
                List<string> messageTypes = __QMessageTmp.Split(new char[] { ',', ';', '|' }, StringSplitOptions.RemoveEmptyEntries).ToList();
                if (Regex.IsMatch(Cmd, @"^QT", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                {
                    foreach (Match m in Regex.Matches(Result, @"([A-Z]{2})\s+(\d{4})\s+(\d{4})", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    {
                        if (Regex.IsMatch(m.Groups[2].Value, @"[1-9]", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                            if (messageTypes.Count(l => l.ToLower().Trim() == m.Groups[1].Value.ToLower().Trim()) > 0)
                            {
                                result.Add(new QResult()
                                {
                                    QMessageType = m.Groups[1].Value,
                                    QMessageCount = m.Groups[2].Value,
                                    QMessage = Result
                                });
                            }
                    }
                }
                #endregion

                if (result.Count > 0)
                {
                    m_TopMessageType = result.FirstOrDefault().QMessageType;
                    SendStream(string.Format(@"QS {0}", m_TopMessageType));
                }
                else
                {
                    SendStream(@"QNE");
                }
            }
            return null;
        }

        /// <summary>
        /// 清Q主体
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        private List<QResult> QS(string Cmd, string Result)
        {
            List<QResult> result = new List<QResult>();
            if (Regex.IsMatch(Cmd, @"^QS\s+", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                    var m = Regex.Match(Result, @"(\s+(\([\s0-9]+\)))+", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                    if (m.Success)
                    {
                        result.Add(new QResult()
                        {
                            QMessageNo = m.Groups[1].Captures[1].Value,
                            QMessageCount = m.Groups[1].Captures[0].Value,
                            QMessage = Result,
                            PNRNo = GetPNRCode(Result),
                            HasChanged = HasQMessageChange(Result),
                            EmployeeNo = GetEmployeeNo(Result),
                            QMessageType = m_TopMessageType
                        });
                    }

                SendStream(@"QN");
            }
            return result;
        }

        /// <summary>
        /// Q信息翻页
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        private List<QResult> PN(string Cmd,  string Result)
        {
            List<QResult> results = new List<QResult>();

            if (Regex.IsMatch(Cmd, @"^PN", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                var m = Regex.Match(Result, @"(\s+(\([\s0-9]+\)))+", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (m.Success)
                {
                    results.Add(new QResult()
                    {
                        QMessageNo = m.Groups[1].Captures[1].Value,
                        QMessageCount = m.Groups[1].Captures[0].Value,
                        QMessage = Result,
                        PNRNo = GetPNRCode(Result),
                        HasChanged = HasQMessageChange(Result),
                        EmployeeNo = GetEmployeeNo(Result),
                        QMessageType = m_TopMessageType
                    });
                }


                if (Regex.IsMatch(Result.Trim(), @"\+$", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                {
                    SendStream(@"PN");
                }
                else
                {
                    SendStream(@"QN");
                }

            }

            return results;
        }

        /// <summary>
        /// 自动清下一个Q消息
        /// </summary>
        /// <param name="Cmd"></param>
        /// <param name="Result"></param>
        /// <returns></returns>
        private List<QResult> QN(string Cmd, string Result)
        {
            List<QResult> results = new List<QResult>();

            if (Regex.IsMatch(Cmd, @"^QN([E]{0})", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                var m = Regex.Match(Result, @"(\s+(\([\s0-9]+\)))+", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                if (m.Success)
                {
                    results.Add(new QResult()
                    {
                        QMessageNo = m.Groups[1].Captures[1].Value,
                        QMessageCount = m.Groups[1].Captures[0].Value,
                        QMessage = Result,
                        PNRNo = GetPNRCode(Result),
                        HasChanged = HasQMessageChange(Result),
                        EmployeeNo = GetEmployeeNo(Result),
                        QMessageType = m_TopMessageType
                    });
                }
            }

            if (Regex.IsMatch(Cmd, @"^QN\s+", RegexOptions.IgnoreCase | RegexOptions.Multiline))
            {
                if (Regex.IsMatch(Result.Trim(), @"\+$", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                {
                    SendStream(@"PN");
                }
                else
                {
                    SendStream(@"QN");
                }
            }
            return results;
        }


        #endregion
    }
}
